package com.yourenbang.lingyun.transaction.web.service.impl.pay.transaction;

import com.alibaba.fastjson.JSONObject;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.mq.MqEnum;
import com.yourenbang.lingyun.constants.enums.pay.PayRateEnum;
import com.yourenbang.lingyun.constants.enums.pay.PayTypeEnum;
import com.yourenbang.lingyun.constants.enums.table.PayTransactionEnum;
import com.yourenbang.lingyun.core.util.AssertUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.StringUtils;
import com.yourenbang.lingyun.core.util.date.DateFormat;
import com.yourenbang.lingyun.core.util.date.LocalDateUtils;
import com.yourenbang.lingyun.domain.Merchant21;
import com.yourenbang.lingyun.domain.Terminal21;
import com.yourenbang.lingyun.transaction.constant.LklTransTypeEnum;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.MigrateDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.yxy.LsTradeDTO;
import com.yourenbang.lingyun.transaction.web.service.PayTransactionFormatService;
import com.yourenbang.mcenter.api.model.dto.MqSendMessage;
import com.yourenbang.mcenter.api.service.McenterMqService;
import com.yourenbang.merchant.api.service.yxy.MerchantYxyApiService;
import com.yourenbang.terminal.api.service.RpcYxyTerminalService;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

/**
 * @author qinmingtao
 * desc 乐刷交易格式化
 */
@Service
@Slf4j
public class LsPayTransactionFormatServiceImpl implements PayTransactionFormatService {
    @Autowired
    private MerchantYxyApiService merchantYxyApiService;
    @Autowired
    private RpcYxyTerminalService yxyTerminalService;

    @Autowired
    private McenterMqService mcenterMqService;

    @Override
    public PayTransaction payTransactionFormat(JSONObject jsonObject) {
        KLog.info("乐刷格式化交易推送入参:{}", jsonObject.toJSONString());
        LsTradeDTO lsTradeDTO = jsonObject.toJavaObject(LsTradeDTO.class);
        PayTransaction payTransaction = new PayTransaction();
        payTransaction.setMerchantNo(lsTradeDTO.getCustomerNo());

        Terminal21 terminal21 = yxyTerminalService.getTerminalBySn(lsTradeDTO.getPosSn());
        if (Objects.isNull(terminal21)) {
            MigrateDTO migrateDTO = new MigrateDTO();
            migrateDTO.setData(jsonObject.toJSONString());
            migrateDTO.setFrom(MigrateDTO.FROM_LS);
            migrateDTO.setOpt(MigrateDTO.OPT_TRANSACTION);
            KLog.info("乐刷交易转发合拓联盟，{}", migrateDTO.toJSON());
            MqSendMessage mqSendMessage = new MqSendMessage();
            mqSendMessage.setTopic(MqEnum.MqTopicEnum.topic_trade_lakala);
            mqSendMessage.setTag(MqEnum.MqTagEnum.tag_trade_lakala);
            mqSendMessage.setSendMsg(migrateDTO.toJSON());
            mqSendMessage.setMessageKey(lsTradeDTO.getFlowId());
            mcenterMqService.hetuoSend(mqSendMessage);
            KLog.info("乐刷交易转发合拓联盟，发送结束");
            return null;
        }
        Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(lsTradeDTO.getCustomerNo());
        AssertUtils.isTrue(Objects.nonNull(merchant21), "获取乐刷商户异常");

        payTransaction.setMerchantName(merchant21.getMerchantName());
        payTransaction.setOrderNo(lsTradeDTO.getFlowId());
        payTransaction.setTransactionNo(lsTradeDTO.getFlowId());
        payTransaction.setSysRef(lsTradeDTO.getChannelRefNo());
        payTransaction.setTransactionAmount(lsTradeDTO.getAmount());
        if (Objects.isNull(lsTradeDTO.getTotalFee())) {
            payTransaction.setTransactionFee(BigDecimal.ZERO);
        } else {
            payTransaction.setTransactionFee(lsTradeDTO.getTotalFee());
        }
        payTransaction.setCardFlag(formatCardFlag(lsTradeDTO.getCardType(), lsTradeDTO.getPayType()));
        if (StringUtils.equalsIgnoreCase(lsTradeDTO.getCardType(), "SEMI-CREDIT")) {
            payTransaction.setRemarks("SEMI-CREDIT");
        }
        try {
            if (Objects.nonNull(lsTradeDTO.getRate())) {
                payTransaction.setRate(lsTradeDTO.getRate().multiply(new BigDecimal("100")).intValue());
            } else {
                if (StringUtils.equalsAny(payTransaction.getCardFlag(), PayTransactionEnum.CardFlagEnum.ALIPAY.getCode(),
                        PayTransactionEnum.CardFlagEnum.WECHAT.getCode())) {
                    payTransaction.setRate(PayRateEnum.f38_qr.getShotCode());
                } else {
                    payTransaction.setRate(payTransaction.getTransactionFee().divide(payTransaction.getTransactionAmount(),
                                    4, BigDecimal.ROUND_HALF_UP)
                            .multiply(new BigDecimal("10000")).intValue());
                }
            }
        } catch (Exception e) {
            log.warn("乐刷计算费率失败:{}", lsTradeDTO.toJSON());
        }
        payTransaction.setTerminalId(lsTradeDTO.getPosSn());
        payTransaction.setSn(lsTradeDTO.getPosSn());
        payTransaction.setTransactionCardNo(lsTradeDTO.getCardNo());
        payTransaction.setTransactionCardType(formatCardFlag(lsTradeDTO.getCardType(), lsTradeDTO.getPayType()));
        //payTransaction.setSettlementCardNo("");
        //payTransaction.setSettlementBank("");
        //payTransaction.setSettlementCardType("");
        payTransaction.setStatus(formatTradeStatus(lsTradeDTO.getTransStatus()));
        LocalDateTime transTime = LocalDateTime.now();
        if (StringUtils.isNotBlank(lsTradeDTO.getCreateTime())) {
            transTime = LocalDateUtils.stringToLocalDateTime(lsTradeDTO.getCreateTime(), DateFormat.DATETIME_DEFAULT.getPartten());
        }

        payTransaction.setTransactionTime(transTime);
        payTransaction.setTransactionMonth(LocalDateUtils.localDateTimeByFormat(transTime, DateFormat.DATE_MONTH.getPartten()));
        payTransaction.setTransactionDay(LocalDateUtils.localDateTimeByFormat(transTime, DateFormat.DATE_COMPACT.getPartten()));
        if (Objects.isNull(lsTradeDTO.getWithdrawFee())) {
            payTransaction.setFeeAmt(BigDecimal.ZERO);
        } else {
            payTransaction.setFeeAmt(lsTradeDTO.getWithdrawFee());
        }
        payTransaction.setAccAmt(lsTradeDTO.getSettleAmt());
//        payTransaction.setWithdrawalQueryTime(LocalDateTime.now());
//        payTransaction.setWithdrawalQueryCount(0);
//        payTransaction.setWithdrawalDrawTime(LocalDateTime.now());
//        payTransaction.setWithdrawalDrawCount(0);
        payTransaction.setWithdrawalStatus(PayTransactionEnum.WithdrawalStatusEnum.STATUS_40.getCode());

        payTransaction.setChannelId(merchant21.getChannelId());
        payTransaction.setPlatNo(PlatNoEnums.YXY.getCode());
        payTransaction.setIsDel(false);
        payTransaction.setTransType(formatPledgeStatus(lsTradeDTO));
        //分润标识
        payTransaction.setProfitFlag(checkIsProfitFlag(payTransaction));

        return payTransaction;
    }

    @Override
    public JSONObject dyUrlRequest(String uri, Map<String, Object> bodyJson) {
        return null;
    }

    @Override
    public JSONObject dyUrlRequestByPayType(String uri, Map<String, Object> bodyJson, PayTypeEnum payTypeEnum) {
        return null;
    }

    /**
     * 判断交易状态
     *
     * @param respCode 交易状态
     * @return
     */
    private Short formatTradeStatus(String respCode) {
        if (StringUtils.equalsAny(respCode, "SUCCESS")) {
            return PayTransactionEnum.TransactionStatus.STATUS_10.getCode();
        }
        if (StringUtils.equalsAny(respCode, "INIT")) {
            return PayTransactionEnum.TransactionStatus.STATUS_0.getCode();
        }
        return PayTransactionEnum.TransactionStatus.STATUS_20.getCode();
    }

    /**
     * 判断押金状态
     *
     * @param lsTradeDTO 交易实体
     * @return
     */
    private String formatPledgeStatus(LsTradeDTO lsTradeDTO) {
        if (StringUtils.equalsAny(lsTradeDTO.getDepositFlag(), "Y")) {
            return LklTransTypeEnum.TYPE_412001.getTransType();
        }
        if (StringUtils.equalsAny(lsTradeDTO.getSimFlag(), "Y")) {
            return LklTransTypeEnum.TYPE_012003.getTransType();
        }
        return LklTransTypeEnum.TYPE_012001.getTransType();
    }

    /**
     * 判断交易卡类型
     *
     * @see LsTradeDTO
     */
    private String formatCardFlag(String cardType, String payType) {

        if (StringUtils.equals(payType, "WX")) {
            return PayTransactionEnum.CardFlagEnum.WECHAT.getCode();
        }
        if (StringUtils.equals(payType, "ZFB")) {
            return PayTransactionEnum.CardFlagEnum.ALIPAY.getCode();
        }
        if (StringUtils.equals(payType, "NFC")) {
            if (StringUtils.equals(cardType, "DEBIT")) {
                return PayTransactionEnum.CardFlagEnum.UNIONCODE_DEBIT.getCode();
            } else if (StringUtils.equalsIgnoreCase(cardType, "CREDIT")) {
                return PayTransactionEnum.CardFlagEnum.UNIONCODE_CREDIT.getCode();
            } else {
                return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
            }
        }
        if (StringUtils.equals(cardType, "DEBIT")) {
            return PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode();
        }
        if (StringUtils.equalsIgnoreCase(cardType, "CREDIT") || StringUtils.equalsIgnoreCase(cardType, "SEMI-CREDIT")) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        }
        return cardType + "_" + payType;

    }

    //判断是否计入分润
    private boolean checkIsProfitFlag(PayTransaction payTransaction) {

        //贷记卡且非押金交易,非流量卡交易才计入分润
        if (StringUtils.equalsAny(payTransaction.getCardFlag(),
                PayTransactionEnum.CardFlagEnum.ALIPAY.getCode(),
                PayTransactionEnum.CardFlagEnum.WECHAT.getCode(),
                PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode(),
                PayTransactionEnum.CardFlagEnum.UNIONCODE_CREDIT.getCode(),
                PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode())
                && !StringUtils.equals(LklTransTypeEnum.TYPE_412001.getTransType(), payTransaction.getTransType())
        ) {
            return true;
        }

        return false;
    }
}
